package com.punai.dataanalysis.cblib.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.punai.common.bos.HeaderBo;
import com.punai.common.constant.DictConstants;
import com.punai.common.core.domain.TreeBo;
import com.punai.common.core.page.TableDataInfo;
import com.punai.common.core.text.Convert;
import com.punai.common.exception.ServiceException;
import com.punai.common.utils.*;
import com.punai.dataanalysis.cblib.bo.*;
import com.punai.dataanalysis.cblib.constants.CbLibConstants;
import com.punai.dataanalysis.cblib.mapper.FeePriceMapper;
import com.punai.dataanalysis.cblib.service.WzClFeePriceLibService;
import com.punai.dataanalysis.cblib.vo.FeeChapterTreeVo;
import com.punai.dataanalysis.cblib.vo.FeeListVo;
import com.punai.dataanalysis.other.mapper.OtherModuleMapper;
import com.punai.externalccb.domain.EcoCbfeeitem;
import com.punai.externalccb.mapper.EcoCbfeeitemMapper;
import com.punai.externalccb.mysqlbo.EcoCbfeeitemPriceBo;
import com.punai.standard.domain.*;
import com.punai.standard.mapper.StaClChapterMapper;
import com.punai.standard.mapper.StaClFeeMapper;
import com.punai.standard.mapper.StaVersionMapper;
import org.apache.commons.collections4.ListValuedMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WzClFeePriceLibServiceImpl implements WzClFeePriceLibService {


    @Autowired
    private StaVersionMapper staVersionMapper;
    @Autowired
    private StaClChapterMapper staClChapterMapper;
    @Autowired
    private StaClFeeMapper staClFeeMapper;
    @Autowired
    private EcoCbfeeitemMapper cbfeeitemMapper;
    @Autowired
    private FeePriceMapper feePriceMapper;
    @Autowired
    private OtherModuleMapper otherModuleMapper;


    @Override
    public List<TreeBo> selectTreeData(FeeChapterTreeVo vo) {
        String versionType = vo.getType();
        String specialty = vo.getSpecialty();
        // 获取 sta_version type = 'GX' CL JX   专业  specialty = spec_id 表的
        List<StaVersion> staVersions = staVersionMapper.selectList(
                Wrappers.<StaVersion>lambdaQuery()
                        .eq(StaVersion::getCompanyId, SecurityUtils.getCompanyId())
                        .eq(StaVersion::getType, versionType)
                        .eq(StrUtil.isNotBlank(specialty) , StaVersion::getSpecId, specialty)
        );

        Optional<StaVersion> latestStaVersion = staVersions.stream()
                .max(Comparator.comparing(StaVersion::getCreateTime));

        if (!latestStaVersion.isPresent()) {
            throw new ServiceException("不存在发布的费用项!");
        }
        StaVersion staVersion = latestStaVersion.get();
        String versionId = staVersion.getId();

        List<StaClChapter> staClChapters = staClChapterMapper.selectList(
                Wrappers.<StaClChapter>lambdaQuery()
                        .eq(StaClChapter::getVersionId, versionId)
        );

        return TreeBo.convert(staClChapters);
    }

    @Override
    public TableDataInfo selectFeeList(FeeListVo vo) {
        String versionId = vo.getVersionId();
        String chapterId = vo.getChapterId();

        List<String> chapterIds = new ArrayList<>();

        if (StrUtil.isNotEmpty(chapterId)) {
            chapterIds.add(chapterId);
            List<StaClChapter> childByPid = getClChildByPid(chapterId, versionId);
            if (CollUtil.isNotEmpty(chapterIds)) {
                chapterIds.addAll(childByPid.stream().map(StaClChapter::getId).collect(Collectors.toList()));
            }
        }
        PageUtils.startPage();

        /*************************** 参数准备 *************************/

        String addressStr = vo.getAddressStr();
        String deptStr = vo.getDeptStr();


        List<String> deptList = null;
        if (StrUtil.isNotBlank(deptStr)) {
            deptList = StrUtil.split(deptStr,",");
        }
        if (StrUtil.isNotBlank(vo.getStartTime())) {
            vo.setStartTime(vo.getStartTime() + "-01");
        }
        if (StrUtil.isNotBlank(vo.getEndTime())) {
            int totalDaysOfMonth = DateUtil.getTotalDaysOfMonth(DateUtil.getDate(vo.getEndTime()));
            vo.setEndTime(vo.getEndTime() + "-" + totalDaysOfMonth);
        }
        Map<String,Object> params = new HashMap<>();
        params.put("stagetype",vo.getStagetype());
        params.put("startTime",vo.getStartTime());
        params.put("endTime",vo.getEndTime());
        params.put("address",vo.getAddressStr());
        params.put("code",vo.getCode());
        params.put("name",vo.getName());
        /****************************************************/
        boolean showExist = vo.isShowExist();
        if (showExist) {
            List<StaClFeeBo> staClFeeBos = feePriceMapper.selectListLinkCbfeeItem(versionId, chapterIds, null, deptList, params);
            long total = new PageInfo(staClFeeBos).getTotal();
            // 可以sql直接计算 直接返回
            return new TableDataInfo(staClFeeBos, Convert.toInt(total));
        }


        List<StaClFee> staClFees = staClFeeMapper.selectList(
                Wrappers.<StaClFee>lambdaQuery()
                        .in(chapterIds.size() > 0, StaClFee::getChapterId, chapterIds)
                        .like(StrUtil.isNotBlank(vo.getCode()), StaClFee::getCode, '%' + vo.getCode() + '%' )
                        .like(StrUtil.isNotBlank(vo.getName()), StaClFee::getItemName, '%' +vo.getName() + '%' )
                        .eq(StaClFee::getVersionId, versionId).orderBy(true, true, StaClFee::getOrderNum)
        );


        params.remove("code");
        params.remove("name");

        //
        long total = new PageInfo(staClFees).getTotal();

        List<String> feeCodes = staClFees.stream().map(StaClFee::getCode).collect(Collectors.toList());

        if (CollUtil.isEmpty(feeCodes)) {
          return new TableDataInfo(new ArrayList<>(),0);
        }

        List<EcoCbfeeitemPriceBo> cbfeeitems = cbfeeitemMapper.selectByCodesAndOther(feeCodes,null,deptList,params);

        if (CollUtil.isEmpty(cbfeeitems)) {
          return new TableDataInfo(new ArrayList<>(),0);
        }

        Map<String, List<EcoCbfeeitemPriceBo>> collect = cbfeeitems.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getOrgincode));

        List<StaClFeeBo> result = new ArrayList<>();

        for (StaClFee staClFee : staClFees) {
            String code = staClFee.getCode();
            List<EcoCbfeeitemPriceBo> ecoCbfeeitemPriceBos = collect.get(code);
            StaClFeeBo convert = StaClFeeBo.convert(staClFee);
            setAvgPriceAndAmount(convert,ecoCbfeeitemPriceBos);
            result.add(convert);
        }
        return new TableDataInfo(result, Convert.toInt(total));
    }

    @Override
    public FeepriceAndMMABo getFeeDetailList(FeeListVo vo) {
        String code = vo.getCode();

        String addressStr = vo.getAddressStr();
        String deptStr = vo.getDeptStr();


        List<String> deptList = null;
        if (StrUtil.isNotBlank(deptStr)) {
            deptList = StrUtil.split(deptStr,",");
        }
        if (StrUtil.isNotBlank(vo.getStartTime())) {
            vo.setStartTime(vo.getStartTime() + "-01");
        }
        if (StrUtil.isNotBlank(vo.getEndTime())) {
            int totalDaysOfMonth = DateUtil.getTotalDaysOfMonth(DateUtil.getDate(vo.getEndTime()));
            vo.setEndTime(vo.getEndTime() + "-" + totalDaysOfMonth);
        }
        Map<String,Object> params = new HashMap<>();
        params.put("stagetype",vo.getStagetype());
        params.put("startTime",vo.getStartTime());
        params.put("endTime",vo.getEndTime());
        params.put("address",vo.getAddressStr());

        List<String> codes = new ArrayList<>();
        codes.add(code);
        PageUtils.startPage();
        List<EcoCbfeeitemPriceBo> cbfeeitems = cbfeeitemMapper.selectByCodesAndOther(codes,null,deptList,params);
        long total = new PageInfo(cbfeeitems).getTotal();
        TableDataInfo tableDataInfo = new TableDataInfo(cbfeeitems, Convert.toInt(total));

        //
        FeepriceAndMMABo resBo = new FeepriceAndMMABo();
        resBo.setTableDataInfo(tableDataInfo);
        // MMA
        MMAInfo mmaInfo = getMMAInfo(cbfeeitems);
        resBo.setMmaInfo(mmaInfo);

        EchartsZXInfo zxInfo = getZxInfo(cbfeeitems);
        resBo.setZxInfo(zxInfo);
        return resBo;
    }

    @Override
    public CompareBo getFeeCompareList(FeeListVo vo) {
        CompareBo compareBo = new CompareBo();

        // 处理参数
        boolean stagetypeOpen = vo.isStagetypeOpen();
        boolean deptOpen = vo.isDeptOpen();

        String stagetype = vo.getStagetypeStr();
        List<String> stagetypeList = StrUtil.split(stagetype, ",");

        String code = vo.getCode();


        List<String> deptList = null;
        String deptStr = vo.getDeptStr();
        if (deptOpen && StrUtil.isNotBlank(deptStr)) {
            deptList = StrUtil.split(deptStr,",");
        }
        if (StrUtil.isNotBlank(vo.getStartTime())) {
            vo.setStartTime(vo.getStartTime() + "-01");
        }
        if (StrUtil.isNotBlank(vo.getEndTime())) {
            int totalDaysOfMonth = DateUtil.getTotalDaysOfMonth(DateUtil.getDate(vo.getEndTime()));
            vo.setEndTime(vo.getEndTime() + "-" + totalDaysOfMonth);
        }
        Map<String,Object> params = new HashMap<>();
        params.put("startTime",vo.getStartTime());
        params.put("endTime",vo.getEndTime());
        params.put("address",vo.getAddressStr());

        List<String> codes = new ArrayList<>();
        codes.add(code);

        List<HeaderBo> headerHzBos = new ArrayList<>();
        List<Map<String, Object>> dataHzList = new ArrayList<>();

        List<HeaderBo> headerBos = new ArrayList<>();
        List<Map<String, Object>> dataList = new ArrayList<>();


        setHzInfo(codes,headerHzBos,dataHzList,stagetypeList,deptList,null,stagetypeOpen,deptOpen,params);
        setXmInfo(codes,headerBos,dataList,stagetypeList,deptList,null,stagetypeOpen,deptOpen,params);

        compareBo.setDataHzList(dataHzList);
        compareBo.setHeaderHzBos(headerHzBos);
        compareBo.setDataList(dataList);
        compareBo.setHeaderBos(headerBos);
        return compareBo;
    }

    private void setXmInfo(List<String> codes,List<HeaderBo> headerBos, List<Map<String, Object>> dataList, List<String> stagetypeList, List<String> deptList,
                           List<String> addressList, boolean stagetypeOpen, boolean deptOpen, Map<String, Object> params) {



        List<CbLibConstants.PriceCompareType> xmdbTab = CbLibConstants.PriceCompareType.getXMDBTab();
        if(stagetypeOpen) {
            params.put("stagetypeList",stagetypeList);
            List<EcoCbfeeitemPriceBo> cbfeeXmitems = cbfeeitemMapper.selectByCodesAndOther(codes,addressList,deptList,params);


            createXmHeader(cbfeeXmitems,headerBos,stagetypeList);
            Map<String,String> proIdNameMap = new HashMap<>();
            for (EcoCbfeeitemPriceBo cbfeeitem : cbfeeXmitems) {
                proIdNameMap.put(cbfeeitem.getProId(),cbfeeitem.getProName());
            }

            if (deptOpen) {
                Map<String, List<EcoCbfeeitemPriceBo>> deptGroup = cbfeeXmitems.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getDeptInfo));
                Set<String> deptKeys = deptGroup.keySet();
                List<Map<String,Object>> maps = otherModuleMapper.selectDeptIdName(deptKeys);

                Map<Long, String> deptIdNameMap = IMapUtil.toMap(maps, "deptId", "deptName");

                for (String deptKey : deptKeys) {
                    List<EcoCbfeeitemPriceBo> deptFeeItems = deptGroup.get(deptKey);
                    Map<String, List<EcoCbfeeitemPriceBo>> proGroup = deptFeeItems.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getProId));
                    for (Map.Entry<String, List<EcoCbfeeitemPriceBo>> proEntry : proGroup.entrySet()) {
                        String proId = proEntry.getKey();
                        String proName = proIdNameMap.get(proId);
                        List<EcoCbfeeitemPriceBo> value = proEntry.getValue();

                        // 通过月份分组
                        ListValuedMap<String,EcoCbfeeitemPriceBo> dateGroup = new ArrayListValuedHashMap<>();
                        for (EcoCbfeeitemPriceBo fip : value) {
                            Date createTime = fip.getCreateTime();
                            dateGroup.put(DateUtil.dateToyM(createTime),fip);
                        }
                        Set<String> keys = dateGroup.keySet();
                        ArrayList<String> listKeys = new ArrayList<>(keys);
                        listKeys.sort(String::compareTo);

                        Map<String, Object> dataItem = new HashMap<>();

                        dataItem.put("fgs",deptIdNameMap.get(Convert.toLong(deptKey)));
                        dataItem.put("proName",proName);

                        for (String key : listKeys) {
                            // 月份分组
                            List<EcoCbfeeitemPriceBo> monthList = dateGroup.get(key);
                            Map<String, List<EcoCbfeeitemPriceBo>> stagetypeGroup = monthList.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getStagetype));

                            for (Map.Entry<String, List<EcoCbfeeitemPriceBo>> stagetypeEntry : stagetypeGroup.entrySet()) {
                                String stagetype = stagetypeEntry.getKey();
                                List<EcoCbfeeitemPriceBo> stagetypeGroupList = stagetypeEntry.getValue();

                                String propStagetype = key + "-" + stagetype;
                                MMAInfo mmaInfo = getMMAInfo(stagetypeGroupList);
                                dataItem.put(propStagetype,mmaInfo.getMaxPrice());

                                for (CbLibConstants.PriceCompareType compareType : xmdbTab) {
                                    String prop = key + "-" + stagetype + "-" + compareType.getProp();
                                    dataItem.put(prop,compareType.getValue(mmaInfo));
                                }
                            }
                        }
                        dataList.add(dataItem);
                    }
                }
            } else {
                Map<String, List<EcoCbfeeitemPriceBo>> proGroup = cbfeeXmitems.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getProId));
                for (Map.Entry<String, List<EcoCbfeeitemPriceBo>> proEntry : proGroup.entrySet()) {
                    String proId = proEntry.getKey();
                    String proName = proIdNameMap.get(proId);
                    List<EcoCbfeeitemPriceBo> value = proEntry.getValue();

                    // 通过月份分组
                    ListValuedMap<String,EcoCbfeeitemPriceBo> dateGroup = new ArrayListValuedHashMap<>();
                    for (EcoCbfeeitemPriceBo fip : value) {
                        Date createTime = fip.getCreateTime();
                        dateGroup.put(DateUtil.dateToyM(createTime),fip);
                    }
                    Set<String> keys = dateGroup.keySet();
                    ArrayList<String> listKeys = new ArrayList<>(keys);
                    listKeys.sort(String::compareTo);

                    Map<String, Object> dataItem = new HashMap<>();

                    dataItem.put("proName",proName);

                    for (String key : listKeys) {
                        // 月份分组
                        List<EcoCbfeeitemPriceBo> monthList = dateGroup.get(key);
                        Map<String, List<EcoCbfeeitemPriceBo>> stagetypeGroup = monthList.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getStagetype));

                        for (Map.Entry<String, List<EcoCbfeeitemPriceBo>> stagetypeEntry : stagetypeGroup.entrySet()) {
                            String stagetype = stagetypeEntry.getKey();
                            List<EcoCbfeeitemPriceBo> stagetypeGroupList = stagetypeEntry.getValue();

                            String propStagetype = key + "-" + stagetype;
                            MMAInfo mmaInfo = getMMAInfo(stagetypeGroupList);
                            dataItem.put(propStagetype,mmaInfo.getMaxPrice());

                            for (CbLibConstants.PriceCompareType compareType : xmdbTab) {
                                String prop = key + "-" + stagetype + "-" + compareType.getProp();
                                dataItem.put(prop,compareType.getValue(mmaInfo));
                            }
                        }
                    }
                    dataList.add(dataItem);
                }
            }
        }
    }

    private void createXmHeader(List<EcoCbfeeitemPriceBo> cbfeeXmitems, List<HeaderBo> headerBos, List<String> stagetypeList) {
        ListValuedMap<String,EcoCbfeeitemPriceBo> headerGroup = new ArrayListValuedHashMap<>();
        for (EcoCbfeeitemPriceBo fip : cbfeeXmitems) {
            Date createTime = fip.getCreateTime();
            headerGroup.put(DateUtil.dateToyM(createTime),fip);
        }
        Set<String> keys = headerGroup.keySet();
        ArrayList<String> monthList = new ArrayList<>(keys);
        monthList.sort(String::compareTo);

        for (String month : monthList) {
            HeaderBo headerBo = new HeaderBo();
            headerBo.setLabel(month);
            List<CbLibConstants.PriceCompareType> xmdbTab = CbLibConstants.PriceCompareType.getXMDBTab();
            for (String stageType : stagetypeList) {
                HeaderBo cbo1 = new HeaderBo();
                cbo1.setLabel( DictUtils.getDictLabel(DictConstants.PROJECT_STAGETYPE,stageType));
                cbo1.setProp(month + "-" + stageType);
                headerBo.getChildren().add(cbo1);

                for (CbLibConstants.PriceCompareType value : xmdbTab) {
                    HeaderBo cbo2 = new HeaderBo();
                    cbo2.setLabel(value.getLabel());
                    cbo2.setProp(month + "-" + stageType + "-" + value.getProp());
                    headerBo.getChildren().add(cbo2);
                }
            }

            headerBos.add(headerBo);
        }


    }

    private void setHzInfo(List<String> codes, List<HeaderBo> headerHzBos, List<Map<String, Object>> dataHzList, List<String> stagetypeList, List<String> deptList,
                           List<String> addressList, boolean stagetypeOpen, boolean deptOpen, Map<String, Object> params) {
        // 对于汇总来讲  不管勾选与否 都会带上筛选条件
        // 而勾选的意义在于 组建结构的不同    分组  +  前面展示的行
        // 查询
        params.put("stagetypeList",stagetypeList);
        List<EcoCbfeeitemPriceBo> cbfeeHzitems = cbfeeitemMapper.selectByCodesAndOther(codes,addressList,deptList,params);



        createHzHeader(cbfeeHzitems,headerHzBos);

        // 求整体的
        if (stagetypeOpen && deptOpen) {
           // 先分公司
            Map<String, List<EcoCbfeeitemPriceBo>> deptGroup = cbfeeHzitems.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getDeptInfo));
            Set<String> deptKeys = deptGroup.keySet();

            List<Map<String,Object>> maps = otherModuleMapper.selectDeptIdName(deptKeys);

            Map<Long, String> deptIdNameMap = IMapUtil.toMap(maps, "deptId", "deptName");

            for (String deptKey : deptKeys) {

                List<EcoCbfeeitemPriceBo> deptFeeItems = deptGroup.get(deptKey);
                // 分阶段
                Map<String, List<EcoCbfeeitemPriceBo>> stagetypeGroup = deptFeeItems.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getStagetype));
                Set<String> keySet = stagetypeGroup.keySet();
                for (String stagetype : keySet) {

                    Map<String, Object> dataItem = new HashMap<>();
                    dataItem.put("fgs",deptIdNameMap.get(Convert.toLong(deptKey)));
                    dataItem.put("stageTypeName",DictUtils.getDictLabel(DictConstants.PROJECT_STAGETYPE,stagetype));

                    List<EcoCbfeeitemPriceBo> ecoCbfeeitemPriceBos = stagetypeGroup.get(stagetype);
                    // 前面几行统计固定的
                    MMAInfo allMMAInfo = getMMAInfo(ecoCbfeeitemPriceBos);
                    CbLibConstants.PriceCompareType[] values = CbLibConstants.PriceCompareType.values();
                    for (CbLibConstants.PriceCompareType value : values) {
                        dataItem.put(value.getProp(),value.getValue(allMMAInfo));
                    }

                    ListValuedMap<String,EcoCbfeeitemPriceBo> dateGroup = new ArrayListValuedHashMap<>();
                    for (EcoCbfeeitemPriceBo fip : ecoCbfeeitemPriceBos) {
                        Date createTime = fip.getCreateTime();
                        dateGroup.put(DateUtil.dateToyM(createTime),fip);
                    }
                    Set<String> keys = dateGroup.keySet();
                    ArrayList<String> monthList = new ArrayList<>(keys);
                    monthList.sort(String::compareTo);
                    for (String key : monthList) {
                        List<EcoCbfeeitemPriceBo> itemPriceLibraryList = dateGroup.get(key);
                        MMAInfo mmaInfo = getMMAInfo(itemPriceLibraryList);
                        for (CbLibConstants.PriceCompareType compareType : values) {
                            String prop = key + "-" + compareType.getProp();
                            dataItem.put(prop,compareType.getValue(mmaInfo));
                        }
                    }
                    // 保存数据
                    dataHzList.add(dataItem);
                }
            }
        } else if (stagetypeOpen) {
            Map<String, List<EcoCbfeeitemPriceBo>> stagetypeGroup = cbfeeHzitems.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getStagetype));
            Set<String> keySet = stagetypeGroup.keySet();
            for (String stagetype : keySet) {

                Map<String, Object> dataItem = new HashMap<>();
                dataItem.put("stageTypeName",DictUtils.getDictLabel(DictConstants.PROJECT_STAGETYPE,stagetype));

                List<EcoCbfeeitemPriceBo> ecoCbfeeitemPriceBos = stagetypeGroup.get(stagetype);
                // 前面几行统计固定的
                MMAInfo allMMAInfo = getMMAInfo(ecoCbfeeitemPriceBos);
                CbLibConstants.PriceCompareType[] values = CbLibConstants.PriceCompareType.values();
                for (CbLibConstants.PriceCompareType value : values) {
                    dataItem.put(value.getProp(),value.getValue(allMMAInfo));
                }

                ListValuedMap<String,EcoCbfeeitemPriceBo> dateGroup = new ArrayListValuedHashMap<>();
                for (EcoCbfeeitemPriceBo fip : ecoCbfeeitemPriceBos) {
                    Date createTime = fip.getCreateTime();
                    dateGroup.put(DateUtil.dateToyM(createTime),fip);
                }
                Set<String> keys = dateGroup.keySet();
                ArrayList<String> monthList = new ArrayList<>(keys);
                monthList.sort(String::compareTo);
                for (String key : monthList) {
                    List<EcoCbfeeitemPriceBo> itemPriceLibraryList = dateGroup.get(key);
                    MMAInfo mmaInfo = getMMAInfo(itemPriceLibraryList);
                    for (CbLibConstants.PriceCompareType compareType : values) {
                        String prop = key + "-" + compareType.getProp();
                        dataItem.put(prop,compareType.getValue(mmaInfo));
                    }
                }
                // 保存数据
                dataHzList.add(dataItem);
            }
        } else if(deptOpen) {
            Map<String, List<EcoCbfeeitemPriceBo>> deptGroup = cbfeeHzitems.stream().collect(Collectors.groupingBy(EcoCbfeeitemPriceBo::getDeptInfo));
            Set<String> deptKeys = deptGroup.keySet();
            for (String deptKey : deptKeys) {
                Map<String, Object> dataItem = new HashMap<>();
                dataItem.put("fgs",deptKey);

                List<EcoCbfeeitemPriceBo> ecoCbfeeitemPriceBos = deptGroup.get(deptKey);
                // 前面几行统计固定的
                MMAInfo allMMAInfo = getMMAInfo(ecoCbfeeitemPriceBos);
                CbLibConstants.PriceCompareType[] values = CbLibConstants.PriceCompareType.values();
                for (CbLibConstants.PriceCompareType value : values) {
                    dataItem.put(value.getProp(),value.getValue(allMMAInfo));
                }

                ListValuedMap<String,EcoCbfeeitemPriceBo> dateGroup = new ArrayListValuedHashMap<>();
                for (EcoCbfeeitemPriceBo fip : ecoCbfeeitemPriceBos) {
                    Date createTime = fip.getCreateTime();
                    dateGroup.put(DateUtil.dateToyM(createTime),fip);
                }
                Set<String> keys = dateGroup.keySet();
                ArrayList<String> monthList = new ArrayList<>(keys);
                monthList.sort(String::compareTo);
                for (String key : monthList) {
                    List<EcoCbfeeitemPriceBo> itemPriceLibraryList = dateGroup.get(key);
                    MMAInfo mmaInfo = getMMAInfo(itemPriceLibraryList);
                    for (CbLibConstants.PriceCompareType compareType : values) {
                        String prop = key + "-" + compareType.getProp();
                        dataItem.put(prop,compareType.getValue(mmaInfo));
                    }
                }
                // 保存数据
                dataHzList.add(dataItem);
            }
        } else {
            Map<String, Object> dataItem = new HashMap<>();
            MMAInfo allMMAInfo = getMMAInfo(cbfeeHzitems);
            CbLibConstants.PriceCompareType[] values = CbLibConstants.PriceCompareType.values();
            for (CbLibConstants.PriceCompareType value : values) {
                dataItem.put(value.getProp(),value.getValue(allMMAInfo));
            }

            ListValuedMap<String,EcoCbfeeitemPriceBo> dateGroup = new ArrayListValuedHashMap<>();
            for (EcoCbfeeitemPriceBo fip : cbfeeHzitems) {
                Date createTime = fip.getCreateTime();
                dateGroup.put(DateUtil.dateToyM(createTime),fip);
            }

            Set<String> keys = dateGroup.keySet();
            ArrayList<String> monthList = new ArrayList<>(keys);
            monthList.sort(String::compareTo);
            for (String key : monthList) {
                List<EcoCbfeeitemPriceBo> itemPriceLibraryList = dateGroup.get(key);
                MMAInfo mmaInfo = getMMAInfo(itemPriceLibraryList);
                for (CbLibConstants.PriceCompareType compareType : values) {
                    String prop = key + "-" + compareType.getProp();
                    dataItem.put(prop,compareType.getValue(mmaInfo));
                }
            }
            // 保存数据
            dataHzList.add(dataItem);
        }
    }

    private void createHzHeader(List<EcoCbfeeitemPriceBo> cbfeeHzitems, List<HeaderBo> headerHzBos) {
        ListValuedMap<String,EcoCbfeeitemPriceBo> headerGroup = new ArrayListValuedHashMap<>();
        for (EcoCbfeeitemPriceBo fip : cbfeeHzitems) {
            Date createTime = fip.getCreateTime();
            headerGroup.put(DateUtil.dateToyM(createTime),fip);
        }
        Set<String> keys = headerGroup.keySet();
        ArrayList<String> monthList = new ArrayList<>(keys);
        monthList.sort(String::compareTo);

        for (String month : monthList) {
            HeaderBo headerBo = new HeaderBo();
            headerBo.setLabel(month);
            CbLibConstants.PriceCompareType[] values = CbLibConstants.PriceCompareType.values();
            for (CbLibConstants.PriceCompareType value : values) {
                HeaderBo cbo = new HeaderBo();
                cbo.setLabel(value.getLabel());
                cbo.setProp(month + "-" + value.getProp());
                headerBo.getChildren().add(cbo);
            }
            headerHzBos.add(headerBo);
        }
    }



    private EchartsZXInfo getZxInfo(List<EcoCbfeeitemPriceBo> cbfeeitems) {
        EchartsZXInfo zxInfo = new EchartsZXInfo();
        ListValuedMap<String,EcoCbfeeitemPriceBo> dateGroup = new ArrayListValuedHashMap<>();
        // 根据月份分组 求平均值
        for (EcoCbfeeitemPriceBo fip : cbfeeitems) {
            Date createTime = fip.getCreateTime();
            dateGroup.put(DateUtil.dateToyM(createTime),fip);
        }
        List<String> names = new ArrayList<>();
        List<BigDecimal> values = new ArrayList<>();
        Set<String> keys = dateGroup.keySet();

        ArrayList<String> listKeys = new ArrayList<>(keys);
        listKeys.sort(String::compareTo);
        for (String key : listKeys) {
            names.add(key);
            List<EcoCbfeeitemPriceBo> itemPriceLibraryList = dateGroup.get(key);
            OptionalDouble average = itemPriceLibraryList.stream().map(EcoCbfeeitemPriceBo::getTargetnotaxprice)
                    .filter(Objects::nonNull).mapToDouble(BigDecimal::doubleValue).average();
            values.add(NumberUtil.getRoundedTY(average.orElse(0)));
        }
        zxInfo.setNames(names);
        zxInfo.setValues(values);
        return zxInfo;
    }

    private List<StaClChapter> getClChildByPid(String chapterId, String versionId) {
        return otherModuleMapper.getClChildByPid(chapterId,versionId);
    }


    private void setAvgPriceAndAmount(StaClFeeBo convert,List<EcoCbfeeitemPriceBo> cbfeeitemPriceBos) {
        // 求数量 和 avg
        if (CollUtil.isNotEmpty(cbfeeitemPriceBos)) {
            convert.setFeeAmount(cbfeeitemPriceBos.size());
            // avg
            OptionalDouble average = cbfeeitemPriceBos.stream().map(EcoCbfeeitemPriceBo::getTargetnotaxprice).mapToDouble(BigDecimal::doubleValue).average();
            if (average.isPresent()) {
                convert.setAvgPrice(NumberUtil.getRoundedTY(average.getAsDouble()));
            }
        }
    }

    private MMAInfo getMMAInfo(List<EcoCbfeeitemPriceBo> cbfeeitems) {
        MMAInfo info = new MMAInfo();
        if (CollUtil.isNotEmpty(cbfeeitems)) {
            OptionalDouble average = cbfeeitems.stream().map(EcoCbfeeitem::getTargetnotaxprice).mapToDouble(BigDecimal::doubleValue).average();
            Optional<BigDecimal> max = cbfeeitems.stream().map(EcoCbfeeitem::getTargetnotaxprice).max(BigDecimal::compareTo);
            Optional<BigDecimal> min = cbfeeitems.stream().map(EcoCbfeeitem::getTargetnotaxprice).min(BigDecimal::compareTo);
            info.setAvgPrice(NumberUtil.getValue(average.orElse(0)));
            info.setMaxPrice(max.orElse(BigDecimal.ZERO));
            info.setMinPrice(min.orElse(BigDecimal.ZERO));
        }
        return info;
    }

}
